#include "Wt.h"

int WtPrintInterpError(WtContext *w)
{
  int rc;
  Tcl_Obj *errInfo, *errCode, *objv[1], *msg;
  char *argv[1], *cmdStr;
  WtInterpContext *active = w->active;
  Tcl_Interp *interp = active->server.interp;

  errInfo = Tcl_GetVar2Ex(interp, "errorInfo", NULL, TCL_GLOBAL_ONLY);
  Tcl_IncrRefCount(errInfo);

  errCode = Tcl_GetVar2Ex(interp, "errorCode", NULL, TCL_GLOBAL_ONLY);
  Tcl_IncrRefCount(errCode);

  if (Tcl_GetCharLength(active->server.errorHandler)) {
    objv[0] = active->server.errorHandler;
    Tcl_IncrRefCount(objv[0]);
    rc = Tcl_EvalObjv(interp, 1, objv, TCL_EVAL_DIRECT);
  } else {
    objv[0] = Tcl_NewStringObj("wt::handleError", -1);
    Tcl_IncrRefCount(objv[0]);
    rc = Tcl_EvalObjv(interp, 1, objv, TCL_EVAL_DIRECT);
    WtApLog(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, w,
      "Wtcl: Command {%s} returned %d.", Tcl_GetString(objv[0]), rc);
  }

  if (rc == TCL_ERROR) {

    msg = Tcl_NewStringObj("\n    while invoking Wtcl error handler\n\"", -1);
    Tcl_IncrRefCount(msg);

    argv[0] = Tcl_GetString(objv[0]);
    cmdStr = Tcl_Merge(1, argv);

    if (cmdStr) {
      Tcl_AppendToObj(msg, cmdStr, -1);
    }

    Tcl_Free(cmdStr);

    Tcl_AppendToObj(msg, "\"", 1);

    if (errInfo && errCode) {
      Tcl_AppendToObj(msg, "\n    with root error\n{", -1);
      Tcl_AppendObjToObj(msg, errInfo);
      Tcl_AppendToObj(msg, "}", 1);
      Tcl_AppendToObj(msg, "\n    with error code\n\"", -1);
      Tcl_AppendObjToObj(msg, errCode);
      Tcl_AppendToObj(msg, "\"", 1);
    }

    Tcl_AppendResult(interp, Tcl_GetString(msg), NULL);
    Tcl_DecrRefCount(msg);

    WtPrintInterpError(w, interp);
  }

  Tcl_DecrRefCount(objv[0]);

  Tcl_DecrRefCount(errInfo);
  Tcl_DecrRefCount(errCode);
}

void WtPrintInterpErrorHtml(WtContext *w, Tcl_Interp *interp)
{
  Tcl_Obj *err;
  /*
  char *bytes;
  int len;
  */

  err = Tcl_NewStringObj(NULL, 0);
  Tcl_IncrRefCount(err);

  Tcl_AppendToObj(err, "<html>\n<head>\n<title>Wtcl Error</title>\n</head>\n<body>\n", -1);
  Tcl_AppendToObj(err, "<h1>Error</h1>\n", -1);
  Tcl_AppendToObj(err, "<p>An error occurred while processing this request:</p>\n", -1);
  Tcl_AppendToObj(err, "<p><ul><pre>\n", -1);
  Tcl_AppendObjToObj(err, Tcl_GetObjResult(interp));
  Tcl_AppendToObj(err, "</pre></ul></p>\n", -1);
  Tcl_AppendToObj(err, "</body>\n</html>\n", -1);

  Tcl_WriteObj(w->webChannel, err);

  /*
  bytes = Tcl_GetStringFromObj(err, &len);
  if (len) {
    ap_rwrite(bytes, len, w->active->request.apReq);
  }
  */

  Tcl_DecrRefCount(err);
}
